package com.avj.g17.chat.server;

import chatcommon.ServerConfig;
import com.avj.g17.chat.common.ChatAPI;
import com.avj.g17.chat.common.ClientCallBack;
import com.avj.g17.chat.common.model.Client;
import com.avj.g17.chat.common.model.Message;
import com.avj.g17.chat.common.model.NotificationMsg;
import com.avj.g17.chat.common.model.User;
import com.avj.g17.chat.server.util.XMLFunctions;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public final class ServerTray {

    public List<Client> listUserOnline = null;
    public Client client = null;
    public Map<User, Message> messages;
    Registry registry = null;

    public ServerTray() {
        try {
            messages = new HashMap<User, Message>();
            listUserOnline = new ArrayList<Client>();
            init();
        } catch (Exception ex) {
        }
    }

    public void init() throws Exception {
        if (!SystemTray.isSupported()) {
            System.out.println("SystemTray is not supported");
            return;
        }

        SystemTray tray = SystemTray.getSystemTray();
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image image = toolkit.getImage("tray-online.png");

        PopupMenu menu = new PopupMenu();

        final MenuItem stop = new MenuItem("Stop Server");
        menu.add(stop);

        final MenuItem start = new MenuItem("Start Server");
        menu.add(start);

        stop.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    stop();
                    if (registry != null) {
                        stop.setEnabled(true);
                        start.setEnabled(false);
                    } else {
                        stop.setEnabled(false);
                        start.setEnabled(true);
                    }
                } catch (NoSuchObjectException ex) {
                }
            }
        });

        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    start();
                    if (registry != null) {
                        stop.setEnabled(true);
                        start.setEnabled(false);
                    } else {
                        stop.setEnabled(false);
                        start.setEnabled(true);
                    }
                } catch (Exception ex) {
                }
            }
        });


        MenuItem closeItem = new MenuItem("Exit");
        closeItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(closeItem);
        TrayIcon icon = new TrayIcon(image, "Chat Server", menu);
        icon.setImageAutoSize(true);
        tray.add(icon);
        start();
        if (registry != null) {
            stop.setEnabled(true);
            start.setEnabled(false);
        } else {
            stop.setEnabled(false);
            start.setEnabled(true);
        }

    }

    private void start() throws RemoteException, MalformedURLException {
        ChatAPI chatAPI = new ServerTray.ChatImpl();
        registry = LocateRegistry.createRegistry(ServerConfig.PORT);
        Naming.rebind("rmi://" + ServerConfig.HOST + ":" + ServerConfig.PORT + "/ChatServer", chatAPI);
        System.out.println("server dang chay");
    }

    private void stop() throws NoSuchObjectException {
        if (registry != null) {
            UnicastRemoteObject.unexportObject(registry, true);
            registry = null;
            System.out.println("Server da stop");
        }
    }

    public class ChatImpl extends UnicastRemoteObject implements ChatAPI {

        public ChatImpl() throws RemoteException {
        }

        @Override
        public void sendMessage(Message message) throws RemoteException {
            if (message != null) {
            } else {

                System.out.println("K co message");
            }
        }

        @Override
        public Message receiveMessage() throws RemoteException {


            return null;
        }

        @Override
        public void registerChatClient(Client c) throws RemoteException {
            client = c;
        }

        @Override
        public boolean login(String username, String password) throws RemoteException {
            try {
                XMLFunctions xmlf = new XMLFunctions();
                Document doc = xmlf.loadXMLFile("data.xml");

                String xquery = "//user[@username='" + username + "' and @password='" + password + "']";
                NodeList list = xmlf.getNodesByXpath(xquery, doc);
                if (list != null) {
                    client.setUsername(username);
                    listUserOnline.add(client);
                    NotificationMsg msg = new NotificationMsg(NotificationMsg.NEW_USERLIST);
                    for (Client c : listUserOnline) {
                        c.getClientCallBack().notifyClient(msg);
                    }
                    System.out.println("Host Client: " + RemoteServer.getClientHost());
                    return true;
                }
                return false;
            } catch (Exception e) {
                return false;
            }
        }

        @Override
        public boolean logout(String username) throws RemoteException {
            Client c = findClient(username);
            if (c != null) {
                listUserOnline.remove(c);
                return true;
            }
            return false;
        }

        @Override
        public List<Client> getListUserOnline() throws RemoteException {
            return listUserOnline;
        }

        @Override
        public void signup(User user) throws RemoteException {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public Client findClient(String username) throws RemoteException {
            for (Client c : listUserOnline) {
                if (c.getUsername().equals(username)) {
                    return c;
                }
            }
            return null;
        }
    }

    public void signup(User user) {
        //To change body of generated methods, choose Tools | Templates.
        try {
            //load xml file

            XMLFunctions xmlf = new XMLFunctions();
            Document doc = xmlf.loadXMLFile("data.xml");
            //create element
            Element node = doc.createElement("user");
            node.setAttribute("Username", "" + user.getUserName());
            node.setAttribute("password", "" + user.getPassword());
            node.appendChild(xmlf.createElementText(doc, "name", "" + user.getFullName() + ""));
            node.appendChild(xmlf.createElementText(doc, "age", "" + user.getAge() + ""));
            node.appendChild(xmlf.createElementText(doc, "gender", "" + user.getGender() + ""));

            doc.getFirstChild().appendChild(node);
            //write xml
            xmlf.writePrettyXML(doc, "data.xml");
        } catch (Exception e) {
        }
    }
}